﻿using System;
using System.Collections.Generic;
using System.Text;
using FeedDotNet.Common;
using System.Security.Cryptography;
using System.IO;
using System.Reflection;
using FeedDotNet;

namespace ConsoleApplication
{
    class MovieFeed : IFeedProvider
    {
        private static SHA1CryptoServiceProvider cryptoTransformSHA1 = new SHA1CryptoServiceProvider();
        private const string cacheDir = "feedCache";
        private string url;

        public MovieFeed(string url)
        {
            this.url = url;
        }
        #region IFeedProvider Members

        public Uri FeedUri
        {
            get { return new Uri(url); }
        }

        protected Feed _feed;
        public Feed FullFeed {
            get { return _feed; }
            set { _feed = value; }
        }

        public string Key
        {
            get { return url; }
        }

        public string Hash
        {
            get { return SHA1Hash(Key); }
        }

        public static string SHA1Hash(string text)
        {
            byte[] buffer = ASCIIEncoding.ASCII.GetBytes(text);
            string hash = 
                BitConverter.ToString(cryptoTransformSHA1.ComputeHash(buffer)).Replace("-", "");
            return hash;
        }

        public virtual void PreProcess(ref Feed newFeed)
        {
        }

        public virtual void PostProcess()
        {
            List<FeedItem> feedItems = new List<FeedItem>();

            if (_feed.Items != null)
            {
                foreach (FeedItem fi in _feed.Items)
                {
                    MovieFeedItem movieItem = new MovieFeedItem(fi);

                    if (movieItem != null)
                        ProcessFeeds.parseMovieInfoFromRSSTitle(movieItem);
                    if (movieItem.Title != "")
                        feedItems.Add(movieItem);
                    if (movieItem.Published == null)
                        movieItem.Published = DateTime.Now;
                }
            }

            _feed.Items = feedItems;
        }

        public virtual void CacheFeed()
        {
            string cacheDirPath = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), cacheDir);
            string cacheFile = Path.Combine(cacheDirPath, string.Concat(Hash, ".xml"));

            try
            {
                if (_feed.Items == null || _feed.Items.Count == 0)
                    throw new Exception("invalid feed... no items");

                if (!Directory.Exists(cacheDirPath))
                    Directory.CreateDirectory(cacheDirPath);

                File.WriteAllText(cacheFile, FeedDotNetExporter.ExportFeed(_feed));
            }
            catch (Exception e)
            {
                Console.Write("failed to cache feed");
                Console.WriteLine(e);
            }
        }

        public virtual List<FeedItem> GetNewFeedItems()
        {
            string cacheDirPath = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), cacheDir);
            string cacheFile = Path.Combine(cacheDirPath, string.Concat(Hash, ".xml"));

            List<FeedItem> newFeedItems;

            if (File.Exists(cacheFile))
            {
                string data = File.ReadAllText(cacheFile);
                Feed oldFeed = FeedReader.ReadString(data);

                newFeedItems = MovieFeedItem.Except(oldFeed.Items, _feed.Items);
            }
            else
            {
                newFeedItems = _feed.Items;
            }

            return newFeedItems;
        }

        #endregion
    }
}
